home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / FALCON / ACC / DRIVERS.ACC / FSMIO.C < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-10  |  44.7 KB  |  1,875 lines

  1. /* FILE:  FSMIO.C
  2.  * ====================================================================
  3.  * DATE:  November 20, 1992
  4.  *      December 8, 1992 - Fixed find_font() to look at the arena
  5.  *                 and not search via the linked list.
  6.  *                 This is because we are preserving the fonts
  7.  *                 as we read them in from the assign.sys and
  8.  *                 do NOT add them via the linked list.
  9.  *      January 15, 1993 - When first brought up, get rid of Assign.old
  10.  *               - While writing assign.sys, first check
  11.  *                 if the assign.old exists. back it up first.
  12.  *               - Write the assign.sys everytime we switch
  13.  *                 printers, paths, add, delete etc.
  14.  *               - If cancel, rename assign.old to assign.sys
  15.  *      January 22, 1993 - Write Header - Take into account
  16.  *                 Date formats for particular countries    
  17.  *
  18.  * INCLUDE FILE: FSMIO.H
  19.  * 
  20.  * DESCRIPTION:
  21.  *
  22.  * Handles the disk IO for the Driver Desk Accessory
  23.  */
  24.  
  25.  
  26.  
  27. /* INCLUDE FILES
  28.  * ====================================================================
  29.  */
  30. #include <sys\gemskel.h>
  31. #include <string.h>
  32.  
  33. #include "country.h" 
  34. #include "drvhead.h"
  35. #include "text.h"
  36. #include "mover.h"
  37.  
  38.  
  39. /* PROTOTYPES
  40.  * ====================================================================
  41.  */
  42. int  kisspace( char thing );
  43.  
  44. void get_bitpath( void );
  45. char *extract_path(int *offset, int max);
  46.  
  47. int  read_fonts( void );
  48. int  get_all_bitmap_fonts( void );
  49. void alpha_bit_add( FON_PTR font );
  50. void free_all_bitmap( void );
  51.  
  52. FON_PTR another_font( void );
  53.  
  54. int  get_drivers( void );
  55. void assign_devices( void );
  56. long read_buffer( int assign, long bytes, char *buffer, int allupper );
  57.  
  58.  
  59. void     ClearDeviceFont( DEV_PTR device );
  60. void     add_to_device( DEV_PTR device, FON_PTR font );
  61. void     remove_from_device( DEV_PTR device, FON_PTR font );
  62. DEV_PTR find_device( int devnum );
  63.  
  64. void    InitDevices( void );
  65. void    InitOneDevice( DEV_PTR device );
  66.  
  67. void    SortDevices( void );
  68. void    SortDriverNames( void );
  69.  
  70. DEV_PTR    AddNewDevice( int devnum );
  71. void    AppendDevice( DEV_PTR device );
  72.  
  73. void     write_assign( void );
  74. void     skip_fontman_header( int old_assign );
  75. void     output_header( int new_assign );
  76. int     output_old_header( int old_assign, int new_assign );
  77. void     write_device( DEV_PTR device, int new_assign );
  78.  
  79. void    CheckMinDevices( void );
  80. char    GetBaseDrive( void );
  81.  
  82. int     find_driver( char *userstring );
  83. long    GetBootDrive( void );
  84.  
  85. void    GetCDrivers( void );
  86. int    *FindString( int *ptr, int *endptr );
  87. void    SortCDriverNames( void );
  88. int    FindCDriverIndex( int dindex );
  89. void    CheckLength( char *text, long limit );
  90.  
  91. FON_PTR find_font( char *userstring );
  92.  
  93. void     CheckOS( void );
  94. long     GetOS( void );
  95.  
  96. void     InitHDrivers( void );
  97. void     ClearHDrivers( void );
  98. void     SetHDrivers( void );
  99. HDEVICE_PTR Find_HDevice( int cnum );
  100. void    DeleteDevice( int num );
  101.  
  102. void     DeleteAssignOld( void );
  103. void     RenameAssignOld( void );
  104.  
  105.  
  106. /* EXTERNS
  107.  * ====================================================================
  108.  */
  109.  
  110.  
  111. /* DEFINES
  112.  * ====================================================================
  113.  */
  114. #define FRONT_LENGTH  27
  115.  
  116. typedef struct _fdata
  117. {
  118.   char pagesize[20];
  119.   char frez[20];
  120.   char fdpi[20];
  121. }FDATA;
  122.  
  123.  
  124.  
  125. /* GLOBALS
  126.  * ====================================================================
  127.  */
  128. char *bufptr;            /* ptr to malloc'ed memory...     */
  129. long BufferSize;        /* Size of ASSIGN.SYS           */
  130.  
  131. int  alen;            /* # bytes we read           */
  132. int  bitmap_found;            /* TRUE for found paths        */
  133.  
  134. DEV  devices[ MAX_DEV + 1 ];    /* Devices */
  135. int  device_count;        /* # devices we know about */
  136. DEV_PTR  current_device;    /* Device position ( Pointer to current device )*/
  137. DEV_PTR  device_head;        /* Pointer to the first device in the linked list
  138.                  * that is not device 0.
  139.                  */
  140. HDEVICE hdrivers[ MAX_DRIVERS ];
  141. HDEVICE_PTR hdriver_head;
  142. char display[ MAX_DRIVERS ][13]; /* Driver Names for Popup */
  143. char drivers[ MAX_DRIVERS ][13];/* Driver names */
  144. int  driver_count;        /* Number of drivers */
  145.  
  146. char  cdrivers[ MAX_DRIVERS ][ 30 ]; /* Driver names for Front Panel */
  147. int   cdriver_array[ MAX_DRIVERS ];  /* Index for cdriver into drivers.*/
  148. int   cdriver_count;
  149. int   cur_cdriver;
  150. FDATA cdriver_data[ MAX_DRIVERS ];  
  151.  
  152.  
  153. FON font_arena[ MAX_FONTS ];    /* We use a static arena */
  154. int free_font[ MAX_FONTS ];    /* Keeps track of what's open */
  155.  
  156. char bitmap_path[ 128 ];    /* Font Path for BITMAP fonts */
  157. FON_PTR bit_list;        /* Font Pointer to Font Arena array
  158.                      * By using the linked list, we can sort
  159.                      * the list etc...
  160.                  */
  161. FON_PTR bit_last;        /* Font Pointer to last font in Font Arena */
  162. int bit_count;            /* The number bitmap fonts available */
  163.  
  164. FON temp_fon[ MAX_FONTS + 2 ];    /* used for copying the fonts from a
  165.                  * driver to be used for displaying in
  166.                  * the mover menu.
  167.                  */
  168. FON_PTR write_fon[ MAX_FONTS + 2 ]; /* Used for copying the fonts from a 
  169.                      * driver to be used for writing out the
  170.                      * fonts during a write assign.sys routine
  171.                      */
  172.                  
  173. char gdos_search[ 128 ];    /* Temp buffer for disk path i/o */
  174. char driver_search[ 128 ];
  175. char assign_search[ 128 ];
  176. char line_buf[ 128 ];
  177. char epath[ 128 ];
  178. char opath[ 128 ];
  179.  
  180. FON_PTR first_font;    /* Used to display the first font in a device */
  181.             /* for displaying in a mover box */
  182.  
  183. int  drv;
  184. char Drive;
  185.  
  186. int  BootDrive;        /* Boot Device - 0x446; */
  187.  
  188. int     *DataBuf;
  189. HEADER  *hdr;
  190. HEADER  hdr_buffer;
  191. MARGIN  *mhdr;
  192.  
  193. HEADER  old_header;
  194.  
  195. long    Buffer;
  196. int    *DataHdr;        /* Word boundary Buffer */
  197. DTA     *olddma, newdma;        /* DTA buffers for _our_ searches */
  198.  
  199. int  Tos_Country;        /* TOS Country Version */
  200.  
  201.  
  202. /* FUNCTIONS
  203.  * ====================================================================
  204.  */
  205.  
  206.  
  207.  
  208.  
  209.  
  210. /* kisspace()
  211.  * ====================================================================
  212.  */
  213. int 
  214. kisspace( char thing )
  215. {
  216.     if ((thing == ' ') || (thing == '\t')) return TRUE;
  217.     else return FALSE;
  218. }
  219.  
  220.  
  221.  
  222. /* another_font()
  223.  * ====================================================================
  224.  */
  225. FON_PTR
  226. another_font( void )
  227. {
  228.     FON_PTR newfont;
  229.     int i;
  230.  
  231.     if( bit_count >= MAX_FONTS )
  232.         return( ( FON_PTR )NULL );
  233.  
  234.     /* Go looking for an open space in the arena */
  235.     i= 0;
  236.     while( ( i < MAX_FONTS) && ( !free_font[i]) ) { ++i; }
  237.     free_font[i] = FALSE;
  238.  
  239.     newfont = &font_arena[i];
  240.     return( newfont );
  241. }
  242.  
  243.  
  244.  
  245. /* free_all_bitmap()
  246.  * ====================================================================
  247.  * Responsible for resetting all the bitmap font parameters to something
  248.  * normal, as well as freeing up all the arena space it's been using.
  249.  * Caller is responsible for re-calling the font reading routines.
  250.  */
  251. void
  252. free_all_bitmap( void )
  253. {
  254.     int i;
  255.     FON_PTR curptr;
  256.         
  257.     for (i = 0; i < MAX_FONTS; ++i)
  258.     {
  259.        /* Free arena space */
  260.        if( !free_font[i] )
  261.         free_font[i] = TRUE;
  262.        curptr = &font_arena[i];
  263.        FNEXT( curptr ) = FPREV( curptr ) = ( FON_PTR )NULL;    
  264.     }
  265.  
  266.     bit_list  = ( FON_PTR )NULL;
  267.     bit_last  = ( FON_PTR )NULL;
  268.     bit_count = 0;
  269.  
  270.     device_count   = 0;          /* Clear device info          */
  271.     current_device = ( DEV_PTR )NULL; /* Clear current device index */
  272.     device_head    = ( DEV_PTR )NULL; /* Clear the device head pointer */
  273.     driver_count   = 0;          /* Clear driver info          */
  274. }
  275.  
  276.  
  277.  
  278.  
  279. /* read_buffer()
  280.  * ====================================================================
  281.  *  Reads in a buffer load of assign.sys, returns the error code if an
  282.  *  error occured.  Otherwise, returns the # of bytes actually read.
  283.  *  If allupper is TRUE, sets all the alphabetic lower case to upper case.
  284.  */
  285. long 
  286. read_buffer( int assign, long bytes, char *buffer, int allupper)
  287. {
  288.     long i, length;        /* Loop counter, # bytes read */
  289.  
  290.     length = Fread( assign, bytes, buffer );
  291.     if (length < 0)
  292.     {
  293.       form_alert(1, alert3 );
  294.     }
  295.     else
  296.     {
  297.       if (allupper)
  298.       {
  299.          for (i = 0; i < length; ++i)
  300.          {
  301.          if ((buffer[i] >= 'a') && (buffer[i] <= 'z'))
  302.          {
  303.            buffer[i] -= 'a' - 'A';
  304.         }
  305.          }
  306.       }
  307.         }
  308.     return length;
  309. }
  310.  
  311.  
  312.  
  313.  
  314. /* extract_path()
  315.  * ====================================================================
  316.  *  Given an index into bufptr, immediately following the keyword that
  317.  *  indicates a path follows, will extract a pointer to the path and
  318.  *  return it.
  319.  */
  320. char
  321. *extract_path( int *offset, int max )
  322. {
  323.     int j;
  324.  
  325.     /* Goes looking for the start of the path */
  326.     while ( ( bufptr[ *offset ] != '=' ) && ( *offset < max ) )
  327.     {
  328.       *offset += 1;
  329.     }
  330.     
  331.     *offset += 1;
  332.     while ( ( kisspace(bufptr[*offset])) && ( *offset < max) )
  333.     {
  334.       *offset += 1;
  335.     }
  336.  
  337.     /* Properly null terminates the path */
  338.     j = *offset;
  339.     while ((bufptr[j] != '\n') && (j < (max - 1)) && (bufptr[j] != '\r')) {++j;}
  340.     bufptr[j] = '\0';
  341.  
  342.     return ( &bufptr[*offset] );
  343. }
  344.  
  345.  
  346.  
  347. /* alpha_bit_add()
  348.  * ====================================================================
  349.  *  Add a font name into the Bitmap font list alphabetically, using strcmp to
  350.  *  determine where the font should be added.
  351.  */
  352. void 
  353. alpha_bit_add( FON_PTR font )
  354. {
  355.         FON_PTR current = bit_list;
  356.         
  357.     if( current == ( FON_PTR )NULL )    /* Add to bare list */
  358.     {
  359.       bit_list      = font;
  360.       bit_last      = font;
  361.       FNEXT( font ) = ( FON_PTR )NULL;
  362.       FPREV( font ) = ( FON_PTR )NULL;
  363.       return;
  364.     }
  365.  
  366.     while( current != ( FON_PTR )NULL )
  367.       current = FNEXT( current );    /* Advance */
  368.  
  369.     if( current == ( FON_PTR )NULL ) /* Add as last */
  370.     {
  371.       FNEXT( bit_last ) = font;
  372.       FPREV( font )     = bit_last;
  373.       FNEXT( font )     = ( FON_PTR )NULL;
  374.       bit_last         = font;
  375.       return;
  376.     }
  377. }
  378.  
  379.  
  380.  
  381.  
  382. /* find_font()
  383.  * ====================================================================
  384.  *  Given the user's string, attempt to match it to an existing font.
  385.  *  If matched successfully, return a pointer to the font's structure.
  386.  * LOOK throught the font arena and do NOT go through the linked list.
  387.  * NULL - IT is a Font, but its not in the list.
  388.  * -1   - It is NOT a font
  389.  */
  390. FON_PTR 
  391. find_font( char *userstring )
  392. {
  393.     FON_PTR search;
  394.     int i, comp;
  395.     char *ptr;
  396.     char no_ext[15];
  397.  
  398.     /* copies 12 characters from the user's string into
  399.      * the local buffer. Finds the .FNT extension and
  400.      * and puts a null there. If it DOESN't find a .FNT,
  401.      * put a NULL at the beginning of the string.
  402.      */
  403.      for( i = 0; i < 12; i++ )
  404.         no_ext[i] = userstring[i];
  405.      no_ext[12] = '\0';
  406.      ptr = strstr( no_ext, ".FNT" );
  407.      if( !ptr )
  408.      {
  409.         no_ext[0] = '\0';
  410.         return( ( FON_PTR )NIL );
  411.      }   
  412.      else
  413.      {
  414.         ptr += 4; /* gets us to the end */
  415.         *ptr = '\0';
  416.      }
  417.         
  418.      
  419.     /* Run through the bitmap fonts list and find the font
  420.        we've just been passed.  If the font name is ever bigger
  421.        than the current search name, we have gone too far!
  422.      */
  423.      
  424.     for( i = 0; i < bit_count; ++i )
  425.     {
  426.        search = &font_arena[i];
  427.        comp = strcmp(  no_ext, FFNAME( search ) );
  428.        if( comp == 0 )
  429.        {
  430.           return( ( FON_PTR )search );
  431.        }
  432.     }
  433.     return( FON_PTR )NULL;
  434. }
  435.  
  436.  
  437.  
  438.  
  439. /* find_driver()
  440.  * ====================================================================
  441.  *  Given the user's string, attempt to match it to an existing driver.
  442.  *  If matched successfully, return a pointer to the driver's string.
  443.  *  Modified to return -1 if not found.
  444.  */
  445. int 
  446. find_driver( char *userstring )
  447. {
  448.     int i;
  449.  
  450.     for( i = 0; i < driver_count; ++i )
  451.     {
  452.        if( strncmp( userstring, drivers[i], strlen( drivers[i] ) ) == 0 )
  453.        {
  454.           return( i );
  455.        }
  456.     }
  457.     return( -1 );
  458. }
  459.  
  460.  
  461.  
  462.  
  463. /* assign_devices()
  464.  * ====================================================================
  465.  *  Reads the ASSIGN.SYS, and for each device number, it tries to
  466.  *  associate a driver (in the driver names list) with it.
  467.  */
  468. void 
  469. assign_devices( void )
  470. {
  471.   DEV_PTR temp_device;
  472.   DEV_PTR tdevice;
  473.  
  474.   FON_PTR t_fon;
  475.   int  drv;                /* Driver # */
  476.   int  assign, dnum, i, j, k;        /* Assign.sys file handle     */
  477.   char drvtype;                /* The "rom" "resident" flags */
  478.  
  479.   device_count   = 0;               /* No devices yet         */
  480.   current_device = ( DEV_PTR )NULL; /* Current device don't exist */
  481.   temp_device    = ( DEV_PTR )NULL; /* No "most recent device"    */
  482.   t_fon          = ( FON_PTR )NULL; /* No "most recent font"      */
  483.  
  484.   sprintf( assign_search, epath );
  485.   /* Open the assign.sys file */
  486.   if( bufptr && (( assign = Fopen( assign_search, 0 )) > 0 ) )
  487.   {
  488.     bitmap_found = TRUE;
  489.        
  490.     do
  491.     {
  492.        if (( alen = ( int )read_buffer( assign, BufferSize, bufptr, TRUE ) ) < 0L )
  493.              return;
  494.  
  495.        /* Skip to the next line */
  496.        i = 0;
  497.        do
  498.        {
  499.            /* Ensure that we have a complete line to parse */
  500.         /* If we don't, we want to read in the line */
  501.         j = i;
  502.         find_newline( j );
  503.  
  504.         if( j == alen )
  505.         {
  506.            strncpy( &bufptr[0], &bufptr[i], j - i );
  507.            if( ( alen = ( int )read_buffer( assign, BufferSize - ( j - i ), 
  508.                  &bufptr[j - i], TRUE )) < 0 )
  509.                  return;
  510.            alen += ( j - i );
  511.            i = 0;
  512.            j = i;
  513.            find_newline( j );
  514.         }
  515.  
  516.         if( ( bufptr[i] >= '0' ) && ( bufptr[i] <= '9' ) )
  517.         {
  518.            /* We've got a device */
  519.            /* Go find it's name in the list */
  520.  
  521.            dnum = atoi(&bufptr[i]);
  522.  
  523.            while( !kisspace( bufptr[i] )) { ++i; }
  524.            if( ( bufptr[i - 1] < '0' ) || ( bufptr[i - 1] > '9' ) )
  525.            {
  526.               drvtype = bufptr[i - 1];
  527.            }
  528.            else
  529.            {
  530.               drvtype = ' ';
  531.            }
  532.            while( kisspace( bufptr[i] ) ) { ++i; } 
  533.  
  534.            j = i;
  535.            find_newline( j );
  536.            bufptr[ j ] = '\0';
  537.  
  538.            /* Look for the Driver, drv == -1 if the driver
  539.             * doesn't exist. ERGO -> 
  540.             * NEED TO CLEAR temp_device and current_device.
  541.             */
  542.            current_device = temp_device = ( DEV_PTR )NULL;
  543.             
  544.            if( (( drv = find_driver( &bufptr[i] )) != -1 ) ||
  545.                (( dnum < 11 ) && (dnum > 0 )) )
  546.            {
  547.               /* If we're past the maximum number of devices
  548.                * allowed, don't add anymore.
  549.                */
  550.               if( device_count < MAX_DEV )
  551.               {
  552.                 /* Screen devices are automagic so, make index 0 */
  553.              if( ( dnum > 0 ) && ( dnum < 11 ) )
  554.              {
  555.                /* we sorted the drivers, so we'll have to look for it */
  556.                if( drv == -1 )    /* Couldn't find driver on disk */
  557.                    drv = find_driver( "SCREEN.SYS" );
  558.                /* We do the check, cause it COULD be a softloaded vdi driver */
  559.              }
  560.              current_device = temp_device = &devices[ device_count ];
  561.              InitOneDevice( temp_device );
  562.  
  563.              DNAME( temp_device )   = drv;
  564.              DDEV( temp_device )    = dnum;
  565.              DTYPE( temp_device )   = drvtype;
  566.              t_fon = (FON_PTR )NULL;
  567.                    
  568.              if( device_count )
  569.              {
  570.                 tdevice = &devices[ device_count - 1 ];
  571.                 DNEXT( tdevice )     = temp_device;
  572.                 DPREV( temp_device ) = tdevice;
  573.              }
  574.              device_count++;
  575.               }
  576.            }
  577.  
  578.            i = j + 1;
  579.         }
  580.         else
  581.         {
  582.            if ((temp_device != ( DEV_PTR )NULL) &&
  583.                ( bufptr[i] != ';'))
  584.            {
  585.                /* See if the font is already in the table */
  586.                t_fon = find_font( &bufptr[i] );
  587.                     
  588.                /* No? Add it to the table - If possible
  589.                 * BUT it IS a .FNT line.
  590.                 */ 
  591.                if( !t_fon )
  592.                {
  593.                /* get an empty slot pointer for the fonts */
  594.                t_fon = another_font();
  595.                if( t_fon ) /* We have an empty slot. */
  596.                {
  597.                   /* Copy name into FFNAME structure */
  598.                   strncpy( FFNAME( t_fon ), &bufptr[i], 12 );
  599.                       FFNAME( t_fon )[12] = '\0';
  600.                   for ( k = 0; k < 12; ++k )
  601.                   {
  602.                     if( FFNAME( t_fon )[k] == '.')
  603.                     {
  604.                    FFNAME( t_fon )[ k + 4 ] = '\0';
  605.                     }
  606.                   }
  607.                   ++bit_count;
  608.                   
  609.                   /* Add to fonts */
  610.                   alpha_bit_add( t_fon );
  611.                       find_newline(i);
  612.                          /*++i;*/
  613.                }
  614.                }
  615.                else
  616.                      find_newline(i);
  617.                
  618.                
  619.                /* find_font returns -1 if it wasn't a font.
  620.                 * so let's NULL t_fon now.
  621.                 */
  622.                if( t_fon == ( FON_PTR )NIL )
  623.                  t_fon = NULL;
  624.                
  625.               /* Add the font to the Device...
  626.                * If we Didn't have a slot, then skip it.
  627.                */
  628.                if( t_fon )
  629.                {
  630.                   add_to_device( temp_device, t_fon );
  631.                }
  632.                else
  633.                find_newline(i);
  634.                ++i;
  635.            }
  636.            else
  637.            {
  638.                  find_newline(i);
  639.              ++i;
  640.            }
  641.          }    
  642.        }while( i < alen );
  643.     }while( alen == BufferSize );
  644.     
  645.       Fclose(assign);
  646.     device_head = &devices[ 0 ];    /* start here by default. */
  647.     SortDevices();
  648.   }                         /* end of if( bitmap_found ) */
  649.   else
  650.   {
  651.     bitmap_found = FALSE;
  652.         device_head  = ( DEV_PTR )NULL;
  653.   }  
  654.               
  655.   /* need to ensure that the screen drivers exist */
  656.   CheckMinDevices();
  657.     
  658.   /* Set the current device to the first device   */
  659.   current_device = device_head;
  660. }
  661.  
  662.  
  663.  
  664. /* get_drivers()
  665.  * ====================================================================
  666.  *  Goes into the GDOS directory (pointed to by the ASSIGN.SYS) and
  667.  *  finds all the drivers (*.SYS).  Inserts those driver names into
  668.  *  an array of names (MAX_DRIVERS drivers).   The ASSIGN.SYS can then
  669.  *  be parsed to link devices with drivers.
  670.  */
  671. int 
  672. get_drivers( void )
  673. {
  674.     int i, j, error;
  675.  
  676.     strcpy( drivers[0], "SCREEN.SYS" );     /* Screen driver is ROM */
  677.     driver_count = 1;
  678.  
  679.     sprintf( driver_search, "%s\\%s", bitmap_path, "*.SYS" );
  680.     error = Fsfirst( driver_search, 0 );/* Normal file search for 1st file */
  681.     if( error != E_OK )              /* No such files! */
  682.     {
  683.       return FALSE;
  684.     }
  685.  
  686.     do
  687.     {
  688.       /* Grab the name out of the DTA structure */
  689.       strncpy( drivers[ driver_count ], ( char * )newdma.d_fname, 12 );
  690.  
  691.       for( i = 0; i < 12; ++i )
  692.       {
  693.          if( drivers[driver_count][i] == '.' )
  694.          {
  695.           drivers[ driver_count ][ i + 4 ] = '\0';
  696.          }
  697.       }
  698.       
  699.         driver_count++;
  700.     } while ( ( Fsnext() == E_OK ) && ( driver_count < MAX_DRIVERS ) );
  701.     SortDriverNames();
  702.  
  703.     /* copy to display string - used for the popup
  704.      * The popup requires that the text strings be terminated
  705.      * with a null. with no multiple blanks before the next string.
  706.      */
  707.     for( i = 0; i < driver_count; i++ )
  708.     {
  709.        /* NULL the entire string FIRST! */
  710.        for( j = 0; j <= 12; j++ )
  711.          display[i][j] = '\0';
  712.        strcpy( display[i], drivers[i] );
  713.     }    
  714.     return( TRUE );
  715. }
  716.  
  717.  
  718.  
  719.  
  720. /* get_all_bitmap_fonts()
  721.  * ====================================================================
  722.  * Reads in the bitmap fonts found in the path described by
  723.  * bitmap_path[].
  724.  * Return 1 if OK
  725.  * return 0 if error - ie: no fonts
  726.  */
  727. int 
  728. get_all_bitmap_fonts( void )
  729. {
  730.         hdriver_head = NULL;
  731.     get_drivers();
  732.     assign_devices();
  733.     GetCDrivers();
  734.     return( TRUE );
  735. }
  736.  
  737.  
  738.  
  739.  
  740.  
  741. /* read_fonts()
  742.  * ====================================================================
  743.  *  Calls the Bitmap routines to find all available fonts and
  744.  *  insert them into the appropriate list.
  745.  *
  746.  *  Returns a 0 on file error.
  747.  */
  748. int 
  749. read_fonts( void )
  750. {
  751.     int error;
  752.     
  753.     bit_list     = ( FON_PTR )NULL;
  754.     bit_count    = 0;
  755.     
  756.     olddma = Fgetdta();    
  757.     Fsetdta( &newdma );        /* Point to OUR buffer */
  758.  
  759.     BufferSize = 0L;
  760.     bufptr     = 0L;
  761.     
  762.     error = Fsfirst( epath, 0 );
  763.     if( error == E_OK )
  764.     {
  765.       bufptr = Malloc( newdma.d_length * 2L );
  766.       if( bufptr )
  767.       {
  768.          BufferSize = newdma.d_length;
  769.       }   
  770.       else
  771.             form_alert( 1, alert4 );
  772.     }
  773.     
  774.     free_all_bitmap();
  775.     InitDevices();
  776.              
  777.     get_all_bitmap_fonts();
  778.     InitHDrivers();
  779.               
  780.     if( bufptr )
  781.     {
  782.       Mfree( bufptr );
  783.              bufptr = 0L;
  784.     }
  785.         Fsetdta( olddma );        /* Point to OLD buffer */
  786.     return( 1 );
  787. }
  788.  
  789.  
  790.  
  791.  
  792. /* get_bitpath()
  793.  * ====================================================================
  794.  * Get the font path from the ASSIGN.SYS
  795.  * If there is NO ASSIGN.SYS, we substitute C: or A: instead.
  796.  *
  797.  */
  798. void 
  799. get_bitpath( void )
  800. {
  801.     int  i, sys_file;
  802.     long j;
  803.     int  error;
  804.     char *fname;
  805.     
  806.     olddma = Fgetdta();    
  807.     Fsetdta( &newdma );        /* Point to OUR buffer */
  808.  
  809.     strcpy( epath, "C:\\ASSIGN.SYS" );
  810.     epath[0] = GetBaseDrive();
  811.  
  812.     strcpy( opath, "C:\\ASSIGN.PRN" );
  813.     opath[0] = GetBaseDrive();
  814.  
  815.     sprintf( bitmap_path, "C:" );
  816.     bitmap_path[0] = GetBaseDrive();
  817.     
  818.     bufptr = 0L;
  819.     BufferSize = 0L;
  820.     
  821.         error = Fsfirst( epath, 0 );/* Normal file search for 1st file */
  822.         if( error == E_OK )             
  823.         {   /* found it! */
  824.             bufptr = Malloc( newdma.d_length * 2L );
  825.         if( bufptr )
  826.         {
  827.             BufferSize = newdma.d_length;
  828.         
  829.         if( (sys_file = Fopen( epath, 0 )) < 0)
  830.         {
  831.               Fsetdta( olddma );        /* Point to OLD buffer */
  832.               if( bufptr )
  833.               {
  834.                   Mfree( bufptr );
  835.                   bufptr = 0L;
  836.               }
  837.                form_alert(1, alert5 );
  838.                return;
  839.             }
  840.  
  841.         bitmap_found = FALSE;
  842.         do
  843.         {
  844.              i = 0;
  845.              alen = (int)Fread( sys_file, BufferSize, bufptr );
  846.              do
  847.              {
  848.                 if( !strncmp( &bufptr[i], "path", 4) ||
  849.                     !strncmp( &bufptr[i], "PATH", 4) )
  850.                 {
  851.                 strcpy( bitmap_path, extract_path( &i, alen ) );
  852.                 bitmap_found = TRUE;
  853.                 goto done;
  854.                }
  855.                   else
  856.                   {
  857.                 while(( bufptr[i] != '\n' ) && ( i < alen )) { ++i; }    /* Skip to newline */
  858.                 ++i;
  859.                 }
  860.              }while( i < alen );
  861.         }while( alen == BufferSize );
  862. done:    
  863.         Fclose( sys_file );
  864.         
  865.         if( bufptr )
  866.         {
  867.            Mfree( bufptr );
  868.            bufptr = 0L;
  869.         }
  870.         j = strlen( bitmap_path );
  871.         if( bitmap_path[ j - 1 ] == '\\' )
  872.             bitmap_path[ j - 1 ] = '\0';
  873.         }
  874.         else
  875.              form_alert( 1, alert4 );
  876.     }
  877.     Fsetdta( olddma );        /* Point to OLD buffer */
  878.     fname = &bitmap_path[0];
  879.     fname = strupr( fname );
  880. }
  881.  
  882.  
  883.  
  884.  
  885.  
  886. /**********************************************************************
  887.  * OUTPUT ASSIGN.SYS
  888.  **********************************************************************
  889.  */
  890.  
  891. /* output_header()
  892.  * ====================================================================
  893.  */
  894. void 
  895. output_header( int new_assign )
  896. {
  897.     long time;
  898.     
  899.     sprintf( line_buf, head1 );
  900.     Fwrite( new_assign, ( long )strlen( line_buf ), line_buf );
  901.     sprintf( line_buf, head2 );
  902.     Fwrite( new_assign, ( long )strlen( line_buf ), line_buf );
  903.  
  904.     time = Gettime();
  905. #if USA    
  906.     sprintf( line_buf, head3, 
  907.         ( int )((  time >> 21 ) & 0x0F ),
  908.         ( int )((  time >> 16 ) & 0x1F ),
  909.         ( int )((( time >> 25 ) & 0x7F ) + 1980),
  910.         ( int )((  time >> 11 ) & 0x1F ),
  911.         ( int )((  time >> 5  ) & 0x3F ) );
  912. #endif
  913.  
  914. #if UK | FRENCH | GERMAN | SPAIN | SWEDEN
  915.     sprintf( line_buf, head3, 
  916.         ( int )((  time >> 16 ) & 0x1F ),
  917.         ( int )((  time >> 21 ) & 0x0F ),
  918.         ( int )((( time >> 25 ) & 0x7F ) + 1980),
  919.         ( int )((  time >> 11 ) & 0x1F ),
  920.         ( int )((  time >> 5  ) & 0x3F ) );
  921. #endif
  922.  
  923.  
  924. #if SWEDEN
  925.     sprintf( line_buf, head3, 
  926.         ( int )((( time >> 25 ) & 0x7F ) + 1980),
  927.         ( int )((  time >> 16 ) & 0x1F ),
  928.         ( int )((  time >> 21 ) & 0x0F ),
  929.         ( int )((  time >> 11 ) & 0x1F ),
  930.         ( int )((  time >> 5  ) & 0x3F ) );
  931. #endif
  932.  
  933.         
  934.     Fwrite( new_assign, ( long )strlen( line_buf ), line_buf );
  935.     sprintf( line_buf, ";>\r\n");
  936.     Fwrite( new_assign, ( long )strlen( line_buf ), line_buf );
  937. }
  938.  
  939.  
  940.  
  941.  
  942. /* write_device()
  943.  * ====================================================================
  944.  */
  945. void 
  946. write_device( DEV_PTR device, int new_assign )
  947. {
  948.         FON_PTR t_fon;
  949.         int  i;
  950.  
  951.     /* Write out the device number, type, and driver name
  952.      * If DTYPE is blank, just don't print it.
  953.      */
  954.     if( DTYPE( device ) == ' ' )
  955.       sprintf( line_buf, "%d %s\r\n\0", DDEV(device), drivers[DNAME(device)] );
  956.     else
  957.       sprintf( line_buf, "%d%c %s\r\n\0", DDEV(device), DTYPE(device ), drivers[DNAME(device)] );
  958.     Fwrite( new_assign, ( long )strlen( line_buf ), line_buf );
  959.  
  960.     for( i = 0; i < DFCOUNT( device ); i++ )
  961.        write_fon[i] = DFONT( device )[i];
  962.     write_fon[ DFCOUNT( device ) ] = ( FON_PTR )NULL;
  963.        
  964.     for( i = 0; i < DFCOUNT( device ); i++ )
  965.     {
  966.        t_fon = write_fon[i];
  967.        if( t_fon )
  968.        {
  969.         sprintf( line_buf, "%s\r\n\0", FFNAME( t_fon ) );
  970.         Fwrite( new_assign, ( long )strlen( line_buf ), line_buf );
  971.        }
  972.     }
  973. }
  974.  
  975.  
  976.  
  977.  
  978.  
  979. /* write_assign()
  980.  * ====================================================================
  981.  * Writes the ASSIGN.SYS file out with the current device and font
  982.  * information.
  983.  */
  984. void 
  985. write_assign( void )
  986. {
  987.     DEV_PTR device;
  988.     int     new_assign;
  989.     long    j;
  990.     int     error;
  991.         
  992.     olddma = Fgetdta();    
  993.     Fsetdta( &newdma );        /* Point to OUR buffer */
  994.     
  995.     /* Look for ASSIGN.PRN. If it exists, leave it.
  996.      * if it doesn't, copy ASSIGN.SYS to ASSIGN.PRN
  997.      */
  998.     error = Fsfirst( opath, 0 );
  999.     if( error != E_OK )
  1000.     {
  1001.        /* Now look for ASSIGN.SYS and rename it to ASSIGN.PRN */
  1002.        error = Fsfirst( epath, 0 );
  1003.        if( error == E_OK )        /* Found it! */
  1004.        {
  1005.          Frename( 0, epath, opath );
  1006.        }
  1007.     }
  1008.  
  1009.  
  1010.     if ((new_assign = Fcreate( epath, 0) ) < 0 )
  1011.     {
  1012.         form_alert(1, alert6 );
  1013.         return;
  1014.     }
  1015.         
  1016.     /* Output commentary at the beginning */
  1017.     output_header( new_assign );
  1018.  
  1019.     /* Now output the path */
  1020.     sprintf( line_buf, "PATH = %s", bitmap_path );
  1021.     j = strlen( line_buf );
  1022.     if( line_buf[ j - 1 ] == ':' )
  1023.         strcat( line_buf, "\\" );
  1024.     strcat( line_buf, "\r\n" );    
  1025.     Fwrite( new_assign, ( long )strlen( line_buf ), line_buf );
  1026.  
  1027.     device = device_head;
  1028.     while( device )
  1029.     {
  1030.        write_device( device, new_assign );
  1031.        device = DNEXT( device );
  1032.     }
  1033.     
  1034.     Fclose( new_assign );
  1035.     Fsetdta( olddma );        /* Point to OLD buffer */
  1036. }
  1037.  
  1038.  
  1039.  
  1040.  
  1041.  
  1042. /* add_to_device()
  1043.  * ====================================================================
  1044.  * appends the given font to the current_device's font list
  1045.  * Find an empty slot in the array and add it to the linked list.
  1046.  */
  1047. void 
  1048. add_to_device( DEV_PTR device, FON_PTR font )
  1049. {
  1050.     FON_PTR t_fon;
  1051.     int    i;
  1052.     
  1053.     for( i = 0; i < MAX_FONTS; i++ )    /* We can change this for MAX_FONTS */
  1054.     {
  1055.        t_fon = DFONT( device )[i];
  1056.        if( t_fon == ( FON_PTR )NULL )
  1057.        {
  1058.          DFCOUNT(device) += 1;
  1059.          DFONT( device )[i] = font;
  1060.          return;
  1061.        }    
  1062.     }
  1063.     /* if we reach this area, we don't have any more space available */    
  1064. }
  1065.  
  1066.  
  1067.  
  1068. /* remove_from_device()
  1069.  * ====================================================================
  1070.  * Removes the given font from the current_device's font list.
  1071.  */
  1072. void 
  1073. remove_from_device( DEV_PTR device, FON_PTR font )
  1074. {
  1075.     FON_PTR t_fon;
  1076.     int     i;
  1077.  
  1078.     i = 0;
  1079.         t_fon = DFONT( device )[i];
  1080.         while( t_fon && ( i < DFCOUNT( device ) ) )
  1081.         {
  1082.            /* Have we found this font? */
  1083.            if( t_fon == font )
  1084.            {
  1085.               DFONT( device )[i] = NULL;
  1086.              
  1087.               /* Now, we move the other fonts down to fill the gap...*/
  1088.               for( i = i; i < DFCOUNT( device ); i++ )
  1089.                  DFONT( device )[i] = DFONT( device )[ i + 1 ];
  1090.               DFONT( device )[ i ] = ( FON_PTR )NULL;
  1091.              DFCOUNT(device) -= 1;
  1092.                    first_font = DFONT( device )[0];
  1093.              return;
  1094.            }
  1095.            else
  1096.            {
  1097.              i++;
  1098.          t_fon = DFONT( device )[i];
  1099.        }  
  1100.         }
  1101.         
  1102. }
  1103.  
  1104.  
  1105.  
  1106. /* ClearDeviceFont()
  1107.  * ====================================================================
  1108.  * Clears out the fonts from the current_device.
  1109.  * DEV_PTR device;    Pointer to device to clear fonts from.
  1110.  */
  1111. void
  1112. ClearDeviceFont( DEV_PTR device )
  1113. {
  1114.    int     i;
  1115.    
  1116.    for( i = 0; i < MAX_FONTS; i++ )
  1117.    {
  1118.       DFONT( device )[ i ] = NULL;   
  1119.    }
  1120.    first_font = ( FON_PTR )NULL;
  1121.    DFCOUNT( device ) = 0;    
  1122. }
  1123.  
  1124.  
  1125.  
  1126. /* find_device()
  1127.  * ====================================================================
  1128.  * Goes looking through our current devices to see if there's a device
  1129.  * with the given number.  If so, return it's pointer, otherwise, NULL;
  1130.  */
  1131. DEV_PTR
  1132. find_device( int devnum )
  1133. {
  1134.     DEV_PTR tdevice;
  1135.  
  1136.     if( device_count )
  1137.     {
  1138.           tdevice = device_head;
  1139.       do
  1140.       {
  1141.         if( DDEV( tdevice ) == devnum )
  1142.             return( tdevice );
  1143.         tdevice = DNEXT( tdevice );            
  1144.       }while( tdevice != ( DEV_PTR )NULL );  
  1145.     }
  1146.     return( ( DEV_PTR )NULL );
  1147. }
  1148.  
  1149.  
  1150.  
  1151. /* Find_HDevice()
  1152.  * ====================================================================
  1153.  * Goes looking through our current devices to see if there's a device
  1154.  * with the given number.  If so, return it's pointer, otherwise, NULL;
  1155.  */
  1156. HDEVICE_PTR
  1157. Find_HDevice( int cnum )
  1158. {
  1159.     HDEVICE_PTR tdevice;
  1160.  
  1161.     if( cdriver_count )
  1162.     {
  1163.           tdevice = hdriver_head;
  1164.       do
  1165.       {
  1166.         if( HNAME( tdevice ) == cnum )
  1167.             return( tdevice );
  1168.             
  1169.         tdevice = HNEXT( tdevice );            
  1170.       }while( tdevice != ( HDEVICE_PTR )NULL );  
  1171.     }
  1172.     return( ( HDEVICE_PTR )NULL );
  1173. }
  1174.  
  1175.  
  1176. /* InitDevices()
  1177.  * ====================================================================
  1178.  * Clears out the whole device array.
  1179.  */
  1180. void
  1181. InitDevices( void )
  1182. {
  1183.    int i;
  1184.    DEV_PTR temp_device;
  1185.    
  1186.    for( i = 0; i <= MAX_DEV; i++ )
  1187.    {
  1188.        temp_device = &devices[ i ];
  1189.        InitOneDevice( temp_device );
  1190.    }
  1191. }
  1192.  
  1193.  
  1194.  
  1195.  
  1196. /* InitOneDevice()
  1197.  * ====================================================================
  1198.  * Clears out a single device.
  1199.  */
  1200. void
  1201. InitOneDevice( DEV_PTR device )
  1202. {
  1203.     DNEXT( device )   = DPREV( device ) = ( DEV_PTR )NULL;
  1204.     DDEV( device )    = 0;
  1205.     DNAME( device )   = 0;
  1206.     DTYPE( device )   = ' ';
  1207.     DFCOUNT( device ) = 0;
  1208.     ClearDeviceFont( device );
  1209. }
  1210.  
  1211.  
  1212.  
  1213.  
  1214.  
  1215. /* AddNewDevice()
  1216.  * ====================================================================
  1217.  * Given a device number, add it to the device linked list.
  1218.  * If the device already exists, or there is no more room in the
  1219.  * device table, return NULL.
  1220.  * When added to the linked list, it is added to the FRONT and then sorted.
  1221.  */
  1222. DEV_PTR
  1223. AddNewDevice( int devnum )
  1224. {
  1225.    DEV_PTR temp_device;
  1226.    int     i;
  1227.    
  1228.    /* Look to see if this device already exists */
  1229.    temp_device = find_device( devnum );
  1230.    
  1231.    if( !temp_device )    /* device doesn't exist, so find an empty slot */
  1232.    {
  1233.       for( i = 0; i < MAX_DEV; i++ )
  1234.       {
  1235.          temp_device = &devices[ i ];    
  1236.          if( !DDEV( temp_device ) )    /* found an empty slot */
  1237.          {
  1238.             InitOneDevice( temp_device );
  1239.             DDEV( temp_device ) = devnum;
  1240.             AppendDevice( temp_device );
  1241.             device_count++;
  1242.         SortDevices();            
  1243.             return( temp_device );
  1244.          }
  1245.       }
  1246.       /* If we reach this point, there were no empty slots. */
  1247.       form_alert( 1, alert7 );
  1248.    }
  1249.    return( ( DEV_PTR )NULL );   
  1250. }
  1251.  
  1252.  
  1253.  
  1254. /* AppendDevice()
  1255.  * ====================================================================
  1256.  * Add the device passed in to the end of the linked list of devices
  1257.  * starting from device_head. Taking into account if device_head is NULL.
  1258.  */
  1259. void
  1260. AppendDevice( DEV_PTR device )
  1261. {
  1262.    DEV_PTR temp_device;
  1263.    
  1264.    temp_device = device_head;
  1265.    
  1266.    if( temp_device )
  1267.    {
  1268.       DNEXT( device )      = temp_device;
  1269.       DPREV( temp_device ) = device;     
  1270.    }
  1271.    else
  1272.    {  /* if device_head is NULL, then we are the first device. */
  1273.       DNEXT( device ) = DPREV( device ) = ( DEV_PTR )NULL;
  1274.    }
  1275.    device_head = device;
  1276. }
  1277.  
  1278.  
  1279.  
  1280. /* SortDevices()
  1281.  * ====================================================================
  1282.  * Sort the Existing devices in the devices[] array.
  1283.  * according to device number. We sort using the linked list.
  1284.  * int device_count == # of devices to sort.
  1285.  * DEV_PTR device_head;  The top pointer to the device in 
  1286.  *             low to high devnum order.
  1287.  */
  1288. void
  1289. SortDevices( void )
  1290. {
  1291.    DEV_PTR a_ptr, b_ptr;
  1292.    DEV_PTR curptr;
  1293.    DEV_PTR next, prev;
  1294.  
  1295.    /* if there are no devices, or the device-head pointer is null, 
  1296.     * we'll just return. And oh yes, if there is only 1 device,
  1297.     * why sort also? :)
  1298.     */   
  1299.    if( !device_count || ( device_count == 1 ) || !device_head )
  1300.        return;
  1301.  
  1302.    curptr = device_head;
  1303.    do
  1304.    {
  1305.       
  1306.       if( DNEXT( curptr ) )
  1307.       {
  1308.         a_ptr = curptr;
  1309.         b_ptr = DNEXT( curptr );
  1310.       
  1311.         if( DDEV( a_ptr ) > DDEV( b_ptr ) )
  1312.         {
  1313.             if( a_ptr == device_head )
  1314.                 device_head = b_ptr;
  1315.  
  1316.  
  1317.         next = DNEXT( b_ptr );
  1318.             prev = DPREV( a_ptr );
  1319.             
  1320.             DNEXT( a_ptr ) = DNEXT( b_ptr );
  1321.             DPREV( a_ptr ) = b_ptr;
  1322.             
  1323.             DNEXT( b_ptr ) = a_ptr;
  1324.             DPREV( b_ptr ) = prev;
  1325.             
  1326.             if( next )
  1327.                  DPREV( next ) = a_ptr;
  1328.                  
  1329.             if( prev )     
  1330.                  DNEXT( prev ) = b_ptr;
  1331.             curptr = device_head;
  1332.         }
  1333.         else
  1334.          curptr = DNEXT( curptr );
  1335.       }
  1336.       else
  1337.        curptr = ( DEV_PTR )NULL;
  1338.       
  1339.    }while( curptr );
  1340. }
  1341.  
  1342.  
  1343. /* SortDriverNames()
  1344.  * ====================================================================
  1345.  * Sorts the resulting driver names in 'drivers[]' into alphabetical 
  1346.  * order...
  1347.  */
  1348. void
  1349. SortDriverNames( void )
  1350. {
  1351.     char  temp[15];    
  1352.     char* item1;
  1353.     char* item2;
  1354.     int   index;
  1355.     
  1356.     index = 0;
  1357.     
  1358.     /* only sort if there is more than one item */
  1359.     if( driver_count > 1 )
  1360.     {
  1361.  
  1362.     do
  1363.     {
  1364.        if( ( index + 1) < driver_count )
  1365.        {
  1366.                item1 = &drivers[ index ][0];
  1367.             item2 = &drivers[ index + 1 ][0];
  1368.            if( strcmp( item1, item2 ) > 0 )
  1369.            {
  1370.           strcpy( &temp[0], item2 );
  1371.           strcpy( item2, item1 );
  1372.           strcpy( item1, &temp[0] );
  1373.           index = 0;
  1374.            }
  1375.            else
  1376.              index++;
  1377.        }
  1378.        else
  1379.          index++;       
  1380.     }while( ( ( index + 1 ) < driver_count ) && ( index < MAX_DRIVERS ) );
  1381.     }
  1382. }
  1383.  
  1384.  
  1385.  
  1386.  
  1387. /* CheckMinDevices()
  1388.  * ====================================================================
  1389.  * Check to make sure that there are at least 01p - 09p devices.
  1390.  */
  1391. void
  1392. CheckMinDevices( void )
  1393. {
  1394.    int     i;
  1395.    DEV_PTR device;
  1396.    int     scrn_id;
  1397.    
  1398.    scrn_id = find_driver( "SCREEN.SYS" );
  1399.       
  1400.    for( i = 1; i < 10; i++ )
  1401.    {
  1402.       device = find_device( i );
  1403.       if( !device )
  1404.       {
  1405.           device = AddNewDevice( i );
  1406.           if( device )
  1407.           {
  1408.             DTYPE( device ) = 'P';    /* Make them in rom...  */
  1409.             /* FORCE TO SCREEN.SYS */
  1410.             if( scrn_id != -1 )
  1411.               DNAME( device ) = scrn_id;
  1412.             else  
  1413.               DNAME( device ) = 0;    /* Make it the first one */
  1414.                               /* Should Never Happen   */
  1415.           }  
  1416.       }    
  1417.    }
  1418. }
  1419.  
  1420.  
  1421.  
  1422. /* GetBaseDrive()
  1423.  * ====================================================================
  1424.  * Get the A drive or C drive for the ASSIGN.SYS based upon
  1425.  * the boot drive.
  1426.  */
  1427. char
  1428. GetBaseDrive( void )
  1429. {
  1430.     char Drive;
  1431.  
  1432.     Supexec( GetBootDrive );
  1433.     Drive = BootDrive + 'A';    
  1434.     return( Drive );
  1435. }
  1436.  
  1437.  
  1438.  
  1439. /* GetBootDrive()
  1440.  * ====================================================================
  1441.  */
  1442. long
  1443. GetBootDrive( void )
  1444. {
  1445.    int *ptr;
  1446.    
  1447.    ptr = ( int *)0x446L;
  1448.    BootDrive = *ptr;
  1449.    return( 0L );
  1450. }
  1451.  
  1452.  
  1453.  
  1454. /* GetCDrivers()
  1455.  * ====================================================================
  1456.  * Go thru the list of .sys files and try to load them.
  1457.  * Those that we can load, get the header and see if they are of the
  1458.  * new driver type. Get the filenames of those that are printer drivers
  1459.  * and store them in cdriver. Store their index into the driver array
  1460.  * into our cdriver array position.
  1461.  *
  1462.  * If the device 21 printer driver has no header, we'll just use 
  1463.  * it's filename.
  1464.  */
  1465. void
  1466. GetCDrivers( void )
  1467. {
  1468.    DTA  thedta, *saved;
  1469.    int  fd;
  1470.    int  *DataPtr;
  1471.    long EndIndex;
  1472.    int  i;
  1473.    DEV_PTR tdevice;
  1474.    int  dindex;
  1475.    saved = Fgetdta();
  1476.    Fsetdta( &thedta );
  1477.    
  1478.    cur_cdriver   =  -1; 
  1479.    cdriver_count =  0;
  1480.    dindex        =  -1;
  1481.    
  1482.    tdevice = find_device( 21 );    /* see if there is a printer device */
  1483.    if( tdevice )
  1484.        dindex  = DNAME( tdevice );  /* get index into the drivers array */
  1485.          
  1486.    for( i = 0; i < driver_count; i++ )    /* Skip the SCREEN.SYS */
  1487.    {
  1488.       sprintf( line_buf, "%s\\%s", bitmap_path, drivers[i] );
  1489.  
  1490.       if( Fsfirst( line_buf, 0 ) <= -1 ) /* Can't find the file... */
  1491.           continue;       /* So, get the next iteration */
  1492.       else
  1493.       {
  1494.          DataBuf = calloc( 1, thedta.d_length * 2L );
  1495.  
  1496.         if( DataBuf )
  1497.         {
  1498.           fd = Fopen( line_buf, 0 );    
  1499.           if( fd > 0 )
  1500.           {
  1501.             Buffer = ( long )DataBuf;
  1502.             Buffer = ( Buffer + 15L ) & 0xFFFFFFF0L;
  1503.             DataHdr = ( int *)Buffer;
  1504.          
  1505.             Fread( fd, thedta.d_length, DataHdr );
  1506.             Fclose( fd );
  1507.      
  1508.             EndIndex = thedta.d_length;
  1509.             DataPtr  = FindString( DataHdr, DataHdr + EndIndex - 8 );
  1510.             if( DataPtr )    /* Look only for new drivers with headers*/
  1511.             {
  1512.               hdr = ( HEADER *)DataPtr;
  1513.               hdr_buffer = ( HEADER )*hdr;
  1514.               hdr = &hdr_buffer;
  1515.  
  1516.           /* want only those drivers with real page sizes */
  1517.           if( hdr->config_map & 0x3E )
  1518.           {
  1519.             /* then get the name...*/
  1520.             strcpy( cdrivers[ cdriver_count ], hdr->fname );
  1521.             cdriver_array[ cdriver_count ] = i;
  1522.             cdriver_count++;
  1523.               }
  1524.               else
  1525.               {
  1526.                 /* Unless it IS the printer device in the assign.sys */                
  1527.                 if( i == dindex )
  1528.                 {
  1529.               strcpy( cdrivers[ cdriver_count ], hdr->fname );
  1530.               cdriver_array[ cdriver_count ] = i;
  1531.               cdriver_count++;
  1532.                 }
  1533.               }  
  1534.             }
  1535.             else    /* unless it is using a printer driver that */
  1536.             {        /* that has no header information           */
  1537.                     /* We'll just use the filename if necessary */
  1538.                     /* BTW- it must be the 21 device...         */
  1539.                 if( i == dindex )
  1540.                 {        
  1541.                   strcpy( cdrivers[ cdriver_count ], drivers[i] );
  1542.                   
  1543.                   strcat( cdrivers[ cdriver_count ], NonSpeedo );
  1544.                   
  1545.                   cdriver_array[ cdriver_count ] = i;
  1546.                   cdriver_count++;
  1547.                 }  
  1548.             }
  1549.         CheckLength( cdrivers[ cdriver_count - 1 ], FRONT_LENGTH );
  1550.           }  
  1551.           free( DataBuf );
  1552.         }
  1553.         else
  1554.         {
  1555.           /* memory error - break out of loop and exit routine */
  1556.           form_alert( 1, alert4 );  
  1557.           break;
  1558.         }  
  1559.       }
  1560.    }  /* end of for */   
  1561.    SortCDriverNames();
  1562.    Fsetdta( saved );    
  1563. }
  1564.  
  1565.  
  1566. /* FindString()
  1567.  * ======================================================================
  1568.  * Look for _FSM_HDR in the drivers 
  1569.  */
  1570. int
  1571. *FindString( int *ptr, int *endptr )
  1572. {
  1573.     long *xptr;
  1574.     
  1575.     while( ptr < endptr )
  1576.     {
  1577.        /* Look for _FSM_HDR */
  1578.        xptr = (long *)ptr;
  1579.        if( ((long)*xptr == 0x5f46534dL ) &&
  1580.            ((long)*(xptr+1) == 0x5f484452L ) )
  1581.        return( ptr );
  1582.        ptr++;
  1583.     }   
  1584.     return( ( int *)NULL );
  1585. }
  1586.  
  1587. /* SortCDriverNames()
  1588.  * ====================================================================
  1589.  * Sort the Front End Driver Names - CDrivers[] into alphabetical order.
  1590.  */
  1591. void
  1592. SortCDriverNames( void )
  1593. {
  1594.     char  temp[30];    
  1595.     char* item1;
  1596.     char* item2;
  1597.     int   index;
  1598.     int   ntemp;
  1599.     FDATA ftemp;
  1600.     index = 0;
  1601.   
  1602.     /* only sort if there is more than one item */
  1603.     if( cdriver_count > 1 )
  1604.     {
  1605.     do
  1606.     {
  1607.        if( ( index + 1) < cdriver_count )
  1608.        {
  1609.                item1 = &cdrivers[ index ][0];
  1610.             item2 = &cdrivers[ index + 1 ][0];
  1611.            if( strcmp( item1, item2 ) > 0 )
  1612.            {
  1613.           strcpy( &temp[0], item2 );
  1614.           strcpy( item2, item1 );
  1615.           strcpy( item1, &temp[0] );
  1616.           
  1617.           ntemp = cdriver_array[ index + 1 ];
  1618.           cdriver_array[ index + 1 ] = cdriver_array[ index ];
  1619.           cdriver_array[ index ] = ntemp;           
  1620.           
  1621.           ftemp = cdriver_data[ index + 1 ];
  1622.           cdriver_data[ index + 1 ] = cdriver_data[ index ];
  1623.           cdriver_data[ index ] = ftemp;
  1624.                       
  1625.           index = 0;
  1626.            }
  1627.            else
  1628.              index++;
  1629.        }
  1630.        else
  1631.          index++;       
  1632.     }while( ( ( index + 1 ) < cdriver_count ) && ( index < MAX_DRIVERS ) );
  1633.     }
  1634.     
  1635. }
  1636.  
  1637.  
  1638. /* InitHDrivers()
  1639.  * ====================================================================
  1640.  */
  1641. void
  1642. InitHDrivers( void )
  1643. {
  1644.     ClearHDrivers();
  1645.     SetHDrivers();
  1646.     
  1647.     if( cdriver_count )
  1648.         hdriver_head = &hdrivers[0];
  1649.  
  1650. }
  1651.  
  1652.  
  1653.  
  1654. /* ClearHDrivers()
  1655.  * ====================================================================
  1656.  */
  1657. void
  1658. ClearHDrivers( void )
  1659. {
  1660.     int i;
  1661.     HDEVICE_PTR cur;
  1662.  
  1663.        for( i = 0; i < MAX_DRIVERS; i++ )
  1664.        {
  1665.           cur = &hdrivers[i];
  1666.           HNAME( cur ) = -1;
  1667.           HNEXT( cur ) = NULL;
  1668.           HFLAG( cur ) = FALSE;
  1669.        }
  1670. }
  1671.        
  1672.  
  1673.  
  1674. /* SetHDrivers()
  1675.  * ====================================================================
  1676.  */
  1677. void
  1678. SetHDrivers( void )
  1679. {
  1680.      int i;
  1681.      HDEVICE_PTR cur, next;
  1682.  
  1683.      for( i = 0; i < cdriver_count; i++ )
  1684.      {
  1685.        cur = &hdrivers[i];
  1686.        next = &hdrivers[i+1];
  1687.        HNAME( cur ) = i;
  1688.        if( ( i + 1 ) >= cdriver_count )
  1689.           HNEXT( cur ) = NULL;
  1690.        else
  1691.           HNEXT( cur ) = next;
  1692.        HFLAG( cur ) = FALSE;
  1693.      }
  1694. }
  1695.  
  1696.  
  1697.  
  1698. /* FindCDriverIndex()
  1699.  * ====================================================================
  1700.  * Given the driver index, we look for that index in the
  1701.  * cdriver_array and get that index for the num into cdriver.
  1702.  */
  1703. int
  1704. FindCDriverIndex( int dindex )
  1705. {
  1706.    int i;
  1707.    
  1708.    for( i = 0; i < cdriver_count; i++ )
  1709.    {
  1710.       if( dindex == cdriver_array[ i ] )
  1711.         return( i );
  1712.    }
  1713.    return( -1 );
  1714. }
  1715.  
  1716.  
  1717.  
  1718. /* CheckLength()
  1719.  * ====================================================================
  1720.  * Checks if the string exceeds the limit, it is then shortened.
  1721.  * Checks if the string is too short, if so, it is padded with blanks 
  1722.  * to the limit.
  1723.  */
  1724. void
  1725. CheckLength( char *text, long limit )
  1726. {
  1727.   long length;
  1728.   
  1729.   length = strlen( text );
  1730.   
  1731.   if( length > limit )
  1732.     text[ limit ] = '\0';
  1733.   else
  1734.   {
  1735.     while( strlen( text ) < limit )
  1736.       strcat( text, " " );
  1737.   }  
  1738. }
  1739.  
  1740.  
  1741.  
  1742.  
  1743.  
  1744. /* CheckOS()    
  1745.  * ================================================================
  1746.  * Checks the OS for version 3.01 of TOS which will have problems
  1747.  * with Bezier functions.
  1748.  */
  1749. void
  1750. CheckOS( void )
  1751. {
  1752.     Supexec( GetOS );
  1753. }
  1754.  
  1755.  
  1756.  
  1757. /* GetOS()
  1758.  * ================================================================
  1759.  * A Supexec routine to get the current version of the OS.
  1760.  */
  1761. long
  1762. GetOS( void )
  1763. {
  1764.    SYSHDR *osheader;
  1765.    
  1766.    osheader = *((SYSHDR **)0x4f2L );
  1767.    
  1768.    osheader = osheader->os_base;
  1769.    Tos_Country  = osheader->os_palmode;
  1770.    return( 0L );
  1771. }
  1772.  
  1773.  
  1774.  
  1775. /* DeleteDevice()
  1776.  * ================================================================
  1777.  * Delete a Device Node along with its associated fonts.
  1778.  */
  1779. void
  1780. DeleteDevice( int num )
  1781. {
  1782.     DEV_PTR curptr;
  1783.     DEV_PTR temp_device;
  1784.         
  1785.     curptr = find_device( num );
  1786.     if( curptr )
  1787.     {
  1788.         if( device_count == 0 ) return;
  1789.  
  1790.         temp_device = curptr;
  1791.         if( DNEXT( curptr ) )
  1792.             DPREV( DNEXT( curptr ) ) = DPREV( curptr );
  1793.         
  1794.         if( DPREV( curptr ) )    
  1795.             DNEXT( DPREV( curptr ) ) = DNEXT( curptr );
  1796.         ClearDeviceFont( curptr );
  1797.     
  1798.     
  1799.         /* Fix up device count */
  1800.         device_count--;
  1801.  
  1802.        /* Change display since we're looking at deleted a device 
  1803.         * We shall use xdevice - 1 if there is no device.
  1804.         */
  1805.         if( DNEXT( curptr ) )
  1806.             curptr = DNEXT( curptr );
  1807.         else
  1808.            curptr = DPREV( curptr );
  1809.          
  1810.         DNEXT( temp_device ) = DPREV( temp_device ) = ( DEV_PTR )NULL;
  1811.         DDEV( temp_device ) = 0;    
  1812.          
  1813.  
  1814.         /* Check if the head device is the one deleted...*/
  1815.         if( temp_device == device_head )
  1816.             device_head = curptr;     
  1817.     }
  1818. }
  1819.  
  1820.  
  1821.  
  1822.  
  1823. /* DeleteAssignOld()
  1824.  * ================================================================
  1825.  * Find and Delete the Assign.prn file
  1826.  */
  1827. void
  1828. DeleteAssignOld( void )
  1829. {
  1830.     int error;
  1831.     
  1832.     olddma = Fgetdta();    
  1833.     Fsetdta( &newdma );        /* Point to OUR buffer */
  1834.  
  1835.     /* Now look for ASSIGN.PRN and DELETE IT! */
  1836.     error = Fsfirst( opath, 0 );
  1837.     if( error == E_OK )        /* Found it! */
  1838.     {
  1839.        Fdelete( opath );       
  1840.     }
  1841.     Fsetdta( olddma );        /* Point to OLD buffer */
  1842. }
  1843.  
  1844.  
  1845.  
  1846. /* RenameAssignOld()
  1847.  * ================================================================
  1848.  * Find and Rename Assign.prn to ASSIGN.SYS
  1849.  * This is called when we cancel.
  1850.  * IF THERE IS NO ASSIGN.prn, THEN WOT?
  1851.  *    1) ERASE ASSIGN.SYS?
  1852.  *    2) WRITE ASSIGN.SYS with only screen devices?
  1853.  */
  1854. void
  1855. RenameAssignOld( void )
  1856. {
  1857.         int error;
  1858.  
  1859.     /* Check if anything has changed..*/
  1860.     if( IsChangeFlag() )
  1861.     {        
  1862.       olddma = Fgetdta();    
  1863.       Fsetdta( &newdma );        /* Point to OUR buffer */
  1864.  
  1865.       /* Now look for ASSIGN.prn and DELETE IT! */
  1866.       error = Fsfirst( opath, 0 );
  1867.       if( error == E_OK )        /* Found it! */
  1868.       {
  1869.         Fdelete( epath );       
  1870.         Frename( 0, opath, epath );  /* Rename to ASSIGN.SYS */
  1871.       }
  1872.       Fsetdta( olddma );        /* Point to OLD buffer */
  1873.     }  
  1874. }
  1875.